package com.myblog.services.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.myblog.Utils.BeanCopyUtils;
import com.myblog.Utils.SecurityUtils;
import com.myblog.domain.GlobalResponse;
import com.myblog.domain.Vo.*;
import com.myblog.domain.contants.GlobalConstants;
import com.myblog.domain.entity.Menu;
import com.myblog.domain.entity.Role;
import com.myblog.domain.entity.RoleMenu;
import com.myblog.domain.entity.enums.GlobalResponseEnum;
import com.myblog.expection.GlobalException;
import com.myblog.mapper.MenuMapper;
import com.myblog.services.MenuService;
import com.myblog.services.RoleMenuService;
import io.jsonwebtoken.lang.Strings;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public  class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService{
    @Resource
    RoleMenuService roleMenuService;
    @Override
    public List<String> getPermissionList(Long id) {
        if(id==1L){
            LambdaQueryWrapper<Menu> queryWrapper=new LambdaQueryWrapper<>();
            queryWrapper.in(Menu::getMenuType, GlobalConstants.MENU_TYPE_BUTTON,GlobalConstants.MENU_TYPE_MENU);
            queryWrapper.eq(Menu::getStatus,GlobalConstants.STATUS_NORMAL);
            List<Menu> menuList = list(queryWrapper);
            List<String> perms = menuList.stream().map(Menu::getPerms).collect(Collectors.toList());
            return perms;
        }
        return baseMapper.selectPermsByUserID(id);
    }

    @Override
    public GlobalResponse getRouters() {
        Long userId = SecurityUtils.getUserId();
        if(userId==1L){
            List<Menu> menuList = baseMapper.selectAllRouterMenu();
            getChildren(menuList);
            return GlobalResponse.ok(new RoutersVo(menuList));
        }
        List<Menu> menuList = baseMapper.getRoutersByUserid(userId);
        List<Menu> menuTree = getChildren(menuList);

//
//        MenuMapper menuMapper = getBaseMapper();
//        List<Menu> menus = null;
//        //判断是否是管理员
//        if(SecurityUtils.isAdmin()){
//            //如果是 获取所有符合要求的Menu
//            menus = menuMapper.selectAllRouterMenu();
//        }else{
//            //否则  获取当前用户所具有的Menu
//            menus = menuMapper.getRoutersByUserid(userId);
//        }
//
//        //构建tree
//        //先找出第一层的菜单  然后去找他们的子菜单设置到children属性中
//        List<Menu> menuTree = builderMenuTree(menus,0L);
//



        return GlobalResponse.ok(new RoutersVo(menuTree));
    }



    @Override
    public GlobalResponse getMenu(String status, String menuName) {
        LambdaQueryWrapper<Menu> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Strings.hasText(status),Menu::getStatus,status);
        lambdaQueryWrapper.like(Strings.hasText(menuName),Menu::getMenuName,menuName);
        List<Menu> menuList = list(lambdaQueryWrapper);
        List<MenuVo> menuVos = BeanCopyUtils.copyBeanList(menuList, MenuVo.class);
        return GlobalResponse.ok(menuVos);
    }

    @Override
    public GlobalResponse saveMenu(Menu menu) {
        save(menu);
        return GlobalResponse.ok();
    }

    @Override
    public GlobalResponse updateMenu(Menu menu) {
        if(Objects.isNull(menu)){
            throw new GlobalException(GlobalResponseEnum.ERROR);
        }

        if(menu.getParentId().equals(menu.getId())){
            throw new GlobalException(GlobalResponseEnum.CANT_MAKE_PARENT_TOSELF);
        }

        if(updateById(menu)){
            return GlobalResponse.ok();
        }
        return GlobalResponse.error(GlobalResponseEnum.ERROR.getCode(),"未修改,请检查id");
    }

    @Override
    public GlobalResponse deleteMenu(String id) {

        LambdaQueryWrapper<Menu> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Menu::getParentId,id);
        List<Menu> list = list(lambdaQueryWrapper);
        if(list.isEmpty()){
            removeById(id);
            return GlobalResponse.ok();
        }
        return GlobalResponse.error(GlobalResponseEnum.ERROR.getCode(),"该菜单有子菜单，请先删除子菜单");
    }

    @Override
    public GlobalResponse getMenuTree() {
        LambdaQueryWrapper<Menu> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.orderByAsc(Menu::getParentId,Menu::getOrderNum);
        List<Menu> menuList = list(lambdaQueryWrapper);
        List<MenuTreeVo> menuTreeVoList = BeanCopyUtils.copyBeanList(menuList, MenuTreeVo.class);
        getChildrenVo(menuTreeVoList);
        return GlobalResponse.ok(menuTreeVoList);
    }



    @Override
    public GlobalResponse getRoleMenuTree(Long roleId) {

        if(roleId.toString().equals(GlobalConstants.TYPE_ADMIN)){
            List<MenuTreeVo> menus= (List<MenuTreeVo>) getMenuTree().getData();
            List<Menu> list = list();
            List<String> checkedKeys = list.stream()
                    .map(menu -> menu.getId().toString()).collect(Collectors.toList());
            return GlobalResponse.ok(new RoleMenuTreeVo(menus,checkedKeys));

        }

        LambdaQueryWrapper<RoleMenu> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(RoleMenu::getRoleId,roleId);
        List<RoleMenu> roleMenu=roleMenuService.list(lambdaQueryWrapper);
        List<Long> menuIdList = roleMenu.stream()
                .map(roleMenu1 -> roleMenu1.getMenuId()).collect(Collectors.toList());

        LambdaQueryWrapper<Menu> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.in(Menu::getId,menuIdList);
        queryWrapper.orderByAsc(Menu::getParentId,Menu::getOrderNum);
        List<Menu> menuList = list(queryWrapper);
        List<MenuTreeVo> menuTreeVoList = BeanCopyUtils.copyBeanList(menuList, MenuTreeVo.class);
        getChildrenVo(menuTreeVoList);

        List<String> checkedKeys = menuIdList.stream()
                .map(id -> id.toString()).collect(Collectors.toList());


        return GlobalResponse.ok(new RoleMenuTreeVo(menuTreeVoList,checkedKeys));
    }

    // 这个地方巨蠢，但是我也不会写，只能这样了
    private List<Menu> getChildren(List<Menu> menuList) {

        for (int i = menuList.size()-1; i >= 0 ; i--) {
            Menu m=menuList.get(i);
            for (int j = i+1; j < menuList.size(); j++) {
                Menu childrenMenu=menuList.get(j);
                if(m.getId().equals(childrenMenu.getParentId())){
                    if(m.getChildren()==null){
                        m.setChildren(new ArrayList<>());
                    }
                    m.getChildren().add(childrenMenu);
                }
            }
        }

        for (int i = 0; i < menuList.size();) {
            if(menuList.get(i).getParentId()!=0){
                menuList.remove(i);
            }else {
                i++;
            }
        }
        return menuList;
    }

    private List<MenuTreeVo> getChildrenVo(List<MenuTreeVo> menuList) {

        for (int i = menuList.size()-1; i >= 0 ; i--) {
            MenuTreeVo m=menuList.get(i);
            for (int j = i+1; j < menuList.size(); j++) {
                MenuTreeVo childrenMenu=menuList.get(j);
                if(m.getId().equals(childrenMenu.getParentId())){
                    if(m.getChildren()==null){
                        m.setChildren(new ArrayList<>());
                    }
                    m.getChildren().add(childrenMenu);
                }
            }
        }

        for (int i = 0; i < menuList.size();) {
            if(menuList.get(i).getParentId()!=0){
                menuList.remove(i);
            }else {
                i++;
            }
        }
        return menuList;
    }

}
